package com.ihr360.encryption;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

public class MysqlCipherInitializer {

    private static final String CIPHER_INSTANCE_NAME = "AES";
    private static final String SECRET_KEY_ALGORITHM = "AES";

    public Cipher prepareAndInitCipher(int encryptionMode, String key) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance(CIPHER_INSTANCE_NAME);
        Key secretKey = generateMySQLAESKey(key, "UTF-8");

        callCipherInit(cipher, encryptionMode, secretKey);
        return cipher;
    }

    void callCipherInit(Cipher cipher, int encryptionMode, Key secretKey) throws InvalidKeyException, InvalidAlgorithmParameterException {
        cipher.init(encryptionMode, secretKey);
    }

    public static SecretKeySpec generateMySQLAESKey(final String key, final String encoding) {
        try {
            final byte[] finalKey = new byte[16];
            int i = 0;
            for (byte b : key.getBytes(encoding)) {
                finalKey[i++ % 16] ^= b;
            }
            return new SecretKeySpec(finalKey, SECRET_KEY_ALGORITHM);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public static SecretKey generateMySQLDESKey(final String key, final String encoding) {
            try{
                final byte[] finalKey = new byte[16];
                int i = 0;
                for (byte b : key.getBytes(encoding)) {
                    finalKey[i++ % 16] ^= b;
                }
                DESKeySpec desKey = new DESKeySpec(finalKey);
                SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
                SecretKey securekey = keyFactory.generateSecret(desKey);
                return securekey;
            }catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException | UnsupportedEncodingException e){
                throw new RuntimeException(e);
            }
    }

}